package com.jackrain.nea.web.controller;

import com.jackrain.nea.core.schema.DBSchemaLoader;
import com.jackrain.nea.core.schema.TableManager;
import com.jackrain.nea.exception.NDSRuntimeException;
import com.jackrain.nea.util.RedisOpsUtil;
import com.jackrain.nea.util.Tools;
import com.jackrain.nea.web.query.QueryListConfigManager;
import com.jackrain.nea.web.webaction.WebActionUtils;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;

import java.util.Iterator;
import java.util.Properties;

/**
 * Created by Lucky dog on 2017/6/27.
 */
@Slf4j
@RestController
public class LoadSchema {

    @Autowired
    private RedisOpsUtil<String,TableManager> redisOpsUtil;

    @Autowired
    private  DBSchemaLoader loader;

    @Autowired
    private  TableManager tm;


    @RequestMapping(path = "/p/c/loadschema",method = RequestMethod.GET)
    protected  String load(){
        try{
            long t=System.currentTimeMillis();
            Properties props= new Properties();
            props.setProperty("directory", "file:/act/tables.portal");
            props.setProperty("defaultTypeConverter","com.jackrain.nea.core.schema.OracleTypeConverter");
            props.setProperty("dbms.type", "oracle");
            long t1 = System.currentTimeMillis();
            init(props,true);
            WebActionUtils.initActions(tm);
            QueryListConfigManager.getInstance().clearAll();


//			 try {
//
//				 FileOutputStream fo = new FileOutputStream("data.ser");
//				 ObjectOutputStream so = new ObjectOutputStream(fo);
//				 so.writeObject(tm);
//				 so.close();
//
//				 FileInputStream in = new FileInputStream("data.ser");
//				 ObjectInputStream is = new ObjectInputStream(in);
//				 TableManager tbm = (TableManager) is.readObject();
//				 long t2 = System.currentTimeMillis();
//				 log.info("runtime:" + (t2-t1));
//
//
//			 } catch (FileNotFoundException e) {
//				 // TODO Auto-generated catch block
//				 e.printStackTrace();
//			 } catch (IOException e) {
//				 // TODO Auto-generated catch block
//				 e.printStackTrace();
//			 }

//			 redisTemplate.setDBIndex(1);
            redisOpsUtil.objRedisTemplate.opsForValue().set("client37", tm);
            long t2 = System.currentTimeMillis();
            log.info("redis runtime:" + (t2-t1));
            t1 = System.currentTimeMillis();
            TableManager managerNew =   redisOpsUtil.objRedisTemplate.opsForValue().get("client37");
            t2 = System.currentTimeMillis();

            log.info(String.valueOf(managerNew.getAllTables().size()));
            log.info(managerNew.getTable("ad_column").getName());
            return "redis runtime:" + (t2-t1);

        }catch(Exception e){
           return e.getMessage();

        }

    }


    /**
     * Initialize the table system. Need to be called once before calling
     * <code>getTable()</code>.
     *
     * @param props including following properties:<br>
     *      "directory" - the absolute file path of table configurations <br>
     *      "defaultTypeConverter" - TypeConverter class name( in fact, this is used for TypeConverterFactory )<br>
     *      if null, will use previous properties set.
     *  @param forceInit if true, the table system should be initialized no matter
     *        it has already be initialized or not
     */
    public synchronized void  init(Properties props, boolean forceInit) {
        // If logging system already initialized, do nothing


        if (tm.isInitialized() && (forceInit ==false) ) {
            return;
        }
        if (tm.isInitializing()) {
            throw new RuntimeException("Schema is initializing, please wait");
        }
        try {



            tm.setInitializing(true);
            if (props != null) {
                tm.setProps(props);
            }
            // init TypeConverterFactory
            //yaoj TypeConverterFactory.getInstance().init(this.props);

            tm.clearAll();
//            Iterator it;
            tm.setDefaultLocale(Tools.getLocale(tm.getProps().getProperty("defaultLocale", "zh_CN")));
            boolean isDebugMode = "true".equalsIgnoreCase(tm.getProps().getProperty("modify", "true"));
            // read from db
            tm.setup(getTablesFromDB());
            tm.checkADTables(isDebugMode);
            tm.setInitialized(true);
            // this check will not prohibit tables from loading into memory
            tm.checkAll();
        }catch(Exception e){
                e.printStackTrace();
                tm.setInitialized(false);
        }finally{
            tm.setInitializing(false);
            loader.destroy();
        }

    }


    private Iterator getTablesFromDB(){

        Iterator it=null;
        try {
            loader.setup(1);
            it=loader.getTables();
            tm.setTableCategories(loader.getTableCategories());
            tm.setSubSystems(loader.getSubSystems());
            tm.setSysModel(loader.getSysModel());
        } catch(Exception e) {
            log.error("Could not get schema structure from db",e);
            throw new NDSRuntimeException("Internal Error, schema could not load from db.", e);
        }
        return it;
    }



}
